﻿using System;

namespace SynergyLib.MusicTheory
{
    /// <suMMary>
    /// Calculates the Frequency in Hz of all piano key notes upon initialization.
    /// </suMMary>
    public static class Pitch
    {

        #region Fields

        //  this is 89 rather than 88 to account for zero-indexing
        public const int TotalNotes = 89;
        static int count;
        /// <suMMary>
        /// An array that stores the frequency of all 88 notes as in the form of Double.
        /// </suMMary>
        internal static float[] FrequencyArray;

        #endregion

       

        #region Public Properties

        

        #endregion

        #region Public Methods

        public static void ConstructPitches()
        {
            PopulateArrays();
        }

        public static float[] GetFrequencyArray()
        {
            return FrequencyArray;
        }
        /// <suMMary>
        /// Returns the array index of a random note.
        /// </suMMary>
        /// <returns></returns>
        /// 
        public static float RandomNote()
        {
            Random r = new Random();
            return KeySignature.CurrentKey[r.Next(0, KeySignature.NonNulls)];
        }

        public static double RiffTest()
        {
            byte[] phrase = { 1, 3, 5, 2, 4, 6, 1, 3, 5 };
            ++count;
            if (count == 9)
            {
                count = 0;
            }
            return KeySignature.CurrentKey[(phrase[count] + 20)];
        }

        #endregion

        #region Private Methods

        /// <suMMary>
        /// Custom math function.  Important for the logarithmic Frequency formula.
        /// </suMMary>
        /// <param name="x"></param>
        /// <returns></returns>
        private static double TwelfthRoot(double x)
        {
            return Math.Pow(x, (1.0 / 12.0));
        }

        /// <suMMary>
        /// Using a single interval as a starting point,
        /// this method calculates the Frequency in Hz of 
        /// the piano key notes.
        /// </suMMary>
        /// <param name="P_a">Reference Pitch.  At least one is required.</param>
        /// <param name="a">Piano Key offset value of the Reference Note.</param>
        /// <param name="n">Piano Key offset value of the note to be calculated.</param>
        /// <returns></returns>
        private static float Calculate_Frequencies(double P_a, byte a, byte n)
        {
            byte n_minus_a = (byte)(n - a);
            return (float)(P_a * Math.Pow(TwelfthRoot(2), n_minus_a));
        }
        /// <suMMary>
        /// Uses the Calculate_Frequencies method to store the resulting values in an array.
        /// Calculates the frequency of every piano key note and 
        /// allocates to an array for easy access.
        /// </suMMary>
        private static void PopulateArrays()
        {
            double freq = 27.5000;  //frequency of A0
            byte init_a = 0;
            float[] freqArray = new float[TotalNotes];
            int[] noteArray = new int[TotalNotes];
            //  Start at second slot to account for the zero-index
            for (byte i = 2; i < TotalNotes; i++)
            {
                //  calculate the frequency of each slot in the frequency array
                freqArray[i] = Calculate_Frequencies(freq, init_a, (byte)(init_a + 1));
                init_a++;
                freq = freqArray[i];
            }
            FrequencyArray = freqArray;
        }

        #endregion
    }
}
